<?php
/**
 * 会員APIコントローラー
 *
 * @package  app
 * @extends  Controller
 */
class Controller_Api_Member extends Controller_Apibase {
	/*
	 * 入力情報
	 */
	public $member_values;

	/**
	 * コンストラクタ
	 *
	 * @access  public
	 * @return  Response
	 */
	public function before() {
		parent::before();
		$post = Input::post();
                
		// 入力情報取得
		// membe_id や point など余計なものは除く
		$this -> member_values = array('push_enable' => null, 'sex' => null, 'birth_date' => null, 'area' => null, );
		foreach ($this->member_values as $key => $value) {
			if (isset($post[$key]) && trim($post[$key]) != "") {
				$this -> member_values[$key] = $post[$key];
			} else {
				unset($this -> member_values[$key]);
			}
		}
	}

	/**
	 * 認証
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_auth() {
	
		return Response::forge(null, D_HTTP_WARNING);
		$post = Input::post();
		$ip_address = Input::real_ip();
		$identification = $post["identification"];
		$uuid = $post['uuid'];

		// 情報取得
		$query = DB::select('member_id', 'member_status', 'identification', 'ip_address');
		$query -> from('member_info');
		$query -> where('uuid', $uuid);
		$result = $query -> execute();

		// レスポンス
		$access_token = md5(time());
		if (count($result) == 0) {
			// 新規会員
			Log::info('new member');

			// 不正チェック
			// 同一MACアドレスで新規ユーザー
			$query = DB::select('uuid');
			$query -> from('member_info');
			$query -> where(array("identification" => $identification));
			$mac = $query -> execute();
			if (count($mac) > 0) {
				$this -> alert(sprintf("mac_address overlap count=%d", count($mac)));
			}
			// 同一IPで連続登録
			$last = DB::expr('DATE_SUB(NOW(),INTERVAL 30 MINUTE)');
			// とりあえず30分以内
			$query = DB::select('uuid');
			$query -> from('member_info');
			$query -> where('ip_address', $ip_address);
			$query -> where('create_date', '>', $last);
			$ip = $query -> execute();
			if (count($ip) > 0) {
				$this -> alert(sprintf("ip_address overlap count=%d", count($mac)));
			}

			// 登録
			$query = DB::insert('member_info');
			$query -> set(array('uuid' => $uuid, 'access_token' => $access_token, 'identification' => $identification, 'ip_address' => $ip_address));
			$query -> execute();
			
			$query = DB::select(DB::expr('last_insert_id() AS member_id'));
			$result = $query -> execute();
			$member = $result -> as_array();
			$member_id = $member[0]['member_id'];

		} else if (count($result) == 1) {
			// 既存会員
			$result = $result[0];
			if (strcmp($result["member_status"], "0") != 0) {
				// 退会済み
				return Response::forge(null, D_HTTP_WARNING);
			}
			$member_id = $result['member_id'];

			// 不正チェック
			// ユーザIDとMACアドレスの紐付け
			if (strcmp($result['identification'], $identification) != 0) {
				$this -> alert("mac_address differ");
			}

			// アクセストークン更新
			$query = DB::update('member_info');
			$query -> set(array("access_token" => $access_token, 'login_date' => DB::expr('NOW()'), 'identification' => $identification, 'ip_address' => $ip_address));
			$query -> where('uuid',$uuid);
			$query -> execute();

		} else {
			// レコード数が変
			return Response::forge(null, D_HTTP_WARNING);
		}
		$json = array('access_token' => $access_token,'member_id' => $member_id);
		
		// 起動時に必要な情報も一緒に返す
		if( isset($post['init']) && $post['init'] == 1) {
			$json['data'] = json_decode($this->get_ranking(3,0),true);
			
			// 広告
			// TODO:ver1.0.1以前のために残している
			$appdriver = Config::get('reward_appdrv_ids');
			$json["appdriver"] = isset($appdriver[$this->appver()]) ? $appdriver[$this->appver()] : $appdriver['default'];

			//　成果発生済み
			$this -> member_where_info = array('member_status' => 0, 'member_id' => $member_id, 'access_token' => $access_token );
			$this -> member_where_other = array('member_id' => $member_id);
			$json['outcome'] = $this -> get_outcome();
		}
		
		return Response::forge(json_encode($json), D_HTTP_UPDATE);
	}

	/**
	 * 取得
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_get() {
		//　成果
		$outcome = $this -> get_outcome();

		$views = $this -> member_result;
		$views['outcome'] = $outcome;

		// ポイントの有効期限を確認
		if ($views['point_has'] != 0) {
			$query = DB::select(DB::expr('COUNT(*) AS count'));
			$query -> from('member_point');
			$query -> where($this -> member_where_other);
			$query -> where('create_date', '>', DB::expr('NOW( ) - INTERVAL ' . Config::get('point_deadline_days') . ' DAY'));
			$result = $query -> execute() -> as_array();
			if ($result[0]['count'] == 0) {
				// 期限内にポイントの移動が無いため、無効にする
				$query = DB::select('point_has');
				$query -> from('member_info');
				$query -> where($this -> member_where_other);
				$result = $query -> execute() -> as_array();
				$point = $result[0]['point_has'];
				if( $point > 0 ) {
					$this->set_outcome($this -> member_where_other['member_id'], 'deadline', '', $point * -1);
				}
				
				$views['point_has'] = '0';
			}
		}

		// 広告
		// TODO:ver1.0.1以前のために残している
		$appdriver = Config::get('reward_appdrv_ids');
		$views["appdriver"] = isset($appdriver[$this->appver()]) ? $appdriver[$this->appver()] : $appdriver['default'];

		return Response::forge(json_encode($views), D_HTTP_UPDATE);
	}

	/**
	 * 更新
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_post() {

		// 更新
		$query = DB::update('member_info');
		$query -> set($this -> member_values);
		$query -> where($this -> member_where_info);
		$query -> execute();

		// レスポンス
		return Response::forge(null, D_HTTP_UPDATE);
	}

	/**
	 * 成果
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_outcome() {
		$post = Input::post();

		// 有効性チェック
		$key1 = $post["key1"];
		$key2 = isset($post["key2"]) ? $post["key2"] : '';
		$done = $this -> get_outcome();
		if (strcmp($done[$key1], '1') == 0) {
			// 成果発生済み
			Log::info('outcome none');
			return Response::forge(null, D_HTTP_WARNING);
		} else {
			// 成果付与
			Log::info('outcome post');
			if ($this -> set_outcome($post['member_id'], $key1, $key2)) {
				return Response::forge(null, D_HTTP_UPDATE);
			} else {
				return Response::forge(null, D_HTTP_WARNING);
			}
		}
	}

	/**
	 * リクエスト
	 *
	 * @access  public
	 * @return  Response
	 */
	public $pointConfig = 200;
	public function action_request() {
		$post = Input::post();

		// バリデーション
		if (empty($post['key1']) || empty($post['key2']) || empty($post['key3']) || empty($post['key4']) || empty($post['key5'])) {
			echo "test";
			$this -> alert('memberrequest postempty');
			return Response::forge(null, D_HTTP_WARNING);
		}
		DB::start_transaction();
		
		// 登録開始
	
		try {
			$point=0;
			if($post['key1']==$this->ITURN_CARD)
			{
				
				if($this -> member_result["point_has"]<$this->pointConfig)
				{
					$this -> alert('memberrequest postempty');
					return Response::forge(null, D_HTTP_WARNING);
				}
				else 
					$point = $this->pointConfig;
			}
			
			
			if($point == 0)
			{
				$point = Config::get('point_rate_song');
			
				if ($this -> member_result["point_has"] < $point) {
					Log::info('memberrequest nopoint');
					return Response::forge(null, D_HTTP_WARNING);
				}
			}
			// リクエスト履歴
			$values = $this -> member_where_other;
			$values['request_status'] = 'new';
			$values['key1'] = $post['key1'];
			$values['key2'] = $post['key2'];
			$values['key3'] = $post['key3'];
			$values['key4'] = $post['key4'];
			$values['key5'] = $post['key5'];
			$query = DB::insert('member_request');
			$query -> set($values);
			$query -> execute();
				// ポイント履歴
			$query = DB::insert('member_point');
			$query -> set(array('member_id' => $this -> member_where_info['member_id'], 'key1' => 'request', 'key2' => '', 'point_value' => $point * -1));
			$query -> execute();
			// ポイントを引く
			$query = DB::update('member_info');
			$query -> set(array("point_has" => DB::expr("point_has-" . $point)));
			$query -> where($this -> member_where_info);
			$query -> execute();

			// コミット
			DB::commit_transaction();
		} catch (\Exception $e) {
			throw $e;
			$this -> alert($e);

			// ロールバック
			DB::rollback_transaction();
			return Response::forge(null, D_HTTP_WARNING);
		}

		return Response::forge(null, D_HTTP_UPDATE);
	}
	 
	 
	public function action_request_test() {
	
		
		//return Response::forge(null, D_HTTP_WARNING);
		$post = Input::post();

		// バリデーション
		if (empty($post['key1']) || empty($post['key2']) || empty($post['key3']) || empty($post['key4']) || empty($post['key5'])) {
			$this -> alert('memberrequest postempty');
			return Response::forge(null, D_HTTP_WARNING);
		}
		
		// 登録開始
		DB::start_transaction();
		try {
			// ポイント残高確認
			$point = Config::get('point_rate_song');
			if ($this -> member_result["point_has"] < $point) {
				Log::info('memberrequest nopoint');
				return Response::forge(null, D_HTTP_WARNING);
			}

			// リクエスト履歴
			$values = $this -> member_where_other;
			$values['request_status'] = 'new';
			$values['key1'] = $post['key1'];
			$values['key2'] = $post['key2'];
			$values['key3'] = $post['key3'];
			$values['key4'] = $post['key4'];
			$values['key5'] = $post['key5'];
			$query = DB::insert('member_request');
			$query -> set($values);
			$query -> execute();

			// ポイント履歴
			$query = DB::insert('member_point');
			$query -> set(array('member_id' => $this -> member_where_info['member_id'], 'key1' => 'request', 'key2' => '', 'point_value' => $point * -1));
			$query -> execute();
			
			// ポイントを引く
			$query = DB::update('member_info');
			$query -> set(array("point_has" => DB::expr("point_has-" . $point)));
			$query -> where($this -> member_where_info);
			$query -> execute();

			// コミット
			DB::commit_transaction();
		} catch (\Exception $e) {
			throw $e;
			$this -> alert($e);

			// ロールバック
			DB::rollback_transaction();
			return Response::forge(null, D_HTTP_WARNING);
		}

		return Response::forge(null, D_HTTP_UPDATE);
	}

	/**
	 * ダウンロード一覧
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_downloadlist() {
		$query = DB::select('request_status', DB::expr('key3 AS song_title'), DB::expr('key4 AS artist'), 'artwork', 'preview', 'giftcode');
		$query -> from('member_request');
		$query -> where($this -> member_where_other);
		$query -> and_where_open();
		$query -> where('request_status', 'send');
		$query -> or_where('request_status', 'new');
		$query -> or_where('request_status', 'done');
		$query -> and_where_close();
		$query -> join('itunes_song', 'LEFT') -> on('itunes_song.itunes_track_id', '=', 'member_request.key2');
		$query -> order_by('request_id', 'DESC');
		$query -> limit(Config::get('maxrows_downloadlist'));
		$json = $query -> execute() -> as_array();

		// ダウンロードリンク作成
		foreach ($json as $key => $value) {
			$link = sprintf("%s%s", Config::get('itunes_gift'), $value['giftcode']);
			$json[$key]['link'] = sprintf("%s/download/itunes/?m=%s&g=%s", Config::get('domain_api'), $this -> member_where_info['member_id'], urlencode($value['giftcode']));
			$json[$key]['close'] = Config::get('itunes_scheme');
			
			if( $value['request_status'] == 'send') {
				// DL可能
				$json[$key]['dl'] = '1';
			} else if( $value['request_status'] == 'done') {
				// DL済み
				$json[$key]['dl'] = '2';
			} else {
				// リクエスト中
				$json[$key]['dl'] = '0';
				$json[$key]['link'] = '';
				$json[$key]['close'] = '';
			}
			unset($json[$key]['request_status']);
		}

		return Response::forge(json_encode($json), D_HTTP_UPDATE);
	}

	/**
	 * 自社ウォール
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_rewardlist() {
		// 審査中の対応
		if( strcmp($this->appver(), Config::get('reward_review')) == 0 ) {
			$review = true;
		} else {
			$review = false;
		}
		
		// 一覧取得
		// 取得済みの物は表示しない
		$sql  = 'SELECT `reward_id`, `post_date`, `title`, `subtitle`, `advertisement`, `notice`, `category`, `description`, `link`, `icon`, `point`';
		$sql .= ' FROM `reward_view`';
		$sql .= ' WHERE del=0';
		if( $review ) {
			$sql .= ' AND review=1';
		}
		$sql .= '  AND NOT EXISTS (SELECT * FROM member_point WHERE member_id=%s AND reward_view.reward_id = member_point.reward_id)';
		$sql .= ' ORDER BY score DESC, create_date DESC, point DESC';
		$query = DB::query( sprintf($sql, $this -> member_where_other['member_id']));
		$json = $query -> execute() -> as_array();
		
		// 編集
		foreach( $json as $key => $value ) {
			// リンクにユーザー情報付与
			$json[$key]['link'] .= $this -> member_where_other['member_id'];
			
			// カテゴリにケツカンマが無い
			if( !empty($json[$key]['category']) && substr($json[$key]['category'], -1, 1) != ',') {
				$json[$key]['category'] .= ',';
			}
			
			// 新着判定
			if( time() - strtotime($json[$key]['post_date']) < 60 * 60 * 24 ) {
				$json[$key]['category'] .= 'new,';
			}
			unset($json[$key]['post_date']);

			// クリック成果
			if( strpos($json[$key]['category'], 'click,') !== false) {
				$json[$key]['link'] = sprintf("%s/api/ad/click/?i=%s&u=%s", Config::get('domain_api'), $json[$key]['reward_id'], $this -> member_where_info['member_id'] );
			}
			
			// 審査中は「WEB」など出さない
			if( $review ) {
				$json[$key]['category'] = '';
			}
			
			// iconに改行が入っていることがある
			$json[$key]['icon'] = str_replace("\r", '', $json[$key]['icon']);
			$json[$key]['icon'] = str_replace("\n", '', $json[$key]['icon']);
		}
		
		return Response::forge(json_encode($json), D_HTTP_UPDATE);
	}

	/**
	 * ポイント履歴
	 *
	 * @access  public
	 * @return  Response
	 */
	public function action_pointlist() {
		$json = array();
		
		// ポイント履歴
		$query = DB::select(DB::expr('UNIX_TIMESTAMP(member_point.create_date) AS dt'), 'key1', 'point_value', 'title');
		$query -> from('member_point');
		$query -> where($this -> member_where_other);
		$query -> where('point_value', '>', 0);
		$query -> join('reward_view', 'LEFT') -> on('reward_view.reward_id', '=', 'member_point.reward_id');
		$query -> order_by('point_id', 'DESC');
		$query -> limit(Config::get('maxrows_downloadlist'));
		$point = $query -> execute() -> as_array();

		// リクエスト履歴
		$query = DB::select(DB::expr('UNIX_TIMESTAMP(create_date) AS dt'), DB::expr('key3 AS song_title'), DB::expr('key4 AS artist') );
		$query -> from('member_request');
		$query -> where($this -> member_where_other);
		$query -> order_by('request_id', 'DESC');
		$query -> limit(Config::get('maxrows_downloadlist'));
		$request = $query -> execute() -> as_array();
		
		// 履歴を一本化
		$list = array_merge( $point, $request);
		usort($list, 'pointlist_sort');
		$list = array_slice($list, 0, Config::get('maxrows_downloadlist'));
		
		// レスポンス作成
		foreach( $list as $k => $v) {
			$t = '';
			if( isset($v['song_title']) ) {
				// リクエスト
				$t = sprintf('%s(%s)をリクエスト申請▲100pt消費', $v['song_title'], $v['artist']);
			} else {
				// ポイント獲得
				switch( $v['key1']) {
					case 'facebook_like':
						$t = sprintf('公式Facebookページをいいね！して%spt獲得', $v['point_value']);
						break;
					case 'twitter_follow':
						$t = sprintf('公式Twitterアカウントをフォローして%spt獲得', $v['point_value']);
						break;
					case 'comment_post':
						$t = sprintf('コメント投稿で%spt獲得', $v['point_value']);
						break;
					case 'login_bonus':
						$t = sprintf('ログインボーナスで%spt獲得', $v['point_value']);
						break;
					default:
						if( !empty($v['title']) ) {
							$t = sprintf('「%s」に登録して%spt獲得', $v['title'], $v['point_value']);
						} else {
							$t = sprintf('登録して%spt獲得', $v['point_value']);
						}
						break;
				}
			}
			
			$json[] = array( 'date' => date('y/m/d', $v['dt']), 'text' => $t);
		}

		return Response::forge(json_encode($json), D_HTTP_UPDATE);
	}

}
function pointlist_sort($a, $b)
{
    if ($a['dt'] == $b['dt']) {
 	    return 0;
    }
    return ($a['dt'] > $b['dt']) ? -1 : 1;
}
